package nl.zoidberg.calculon.engine;

import java.util.HashMap;
import java.util.Map;
import java.util.TreeMap;

import nl.zoidberg.calculon.model.Piece;

public class PawnCaptureGenerator extends PieceMoveGenerator {

	@Override
	public Map<String, Board> generateMoves(Board board, int file, int rank) {
		return this.generateMoves(board, file, rank, false);
	}
	
	@Override
	public Map<String, Board> generateMoves(Board board, int file, int rank, boolean oneOnly) {
		boolean alreadyInCheck = board.isInCheck();
		
		Map<String, Board> rv = new TreeMap<String, Board>();
//		BitBoard bitBoard = board.getBitBoard();

		int nextRank = (board.getPlayer() & Piece.MASK_COLOR) == Piece.WHITE ? 1 : -1;
		
//		if(isEmpty(bitBoard, file, rank + nextRank)) {
//			String move = EngineUtils.toSimpleAlgebraic(file, rank, file, rank + nextRank);
//			addMove(move, board, rv, alreadyInCheck);
//			if(oneOnly && rv.size() > 0) {
//				return rv;
//			}
//			
//			if(rank == homeRank && isEmpty(bitBoard, file, rank + (2*nextRank))) {
//				move = EngineUtils.toSimpleAlgebraic(file, rank, file, rank + (2*nextRank));
//				addMove(move, board, rv, alreadyInCheck);
//				if(oneOnly && rv.size() > 0) {
//					return rv;
//				}
//			}
//		}
		
		if(isCaptureTargetForPawn(board, file-1, rank+nextRank)) {
			String move = EngineUtils.toSimpleAlgebraic(file, rank, file-1, rank + nextRank);
			addMove(move, board, rv, alreadyInCheck);
			if(oneOnly && rv.size() > 0) {
				return rv;
			}
		}
		
		if(isCaptureTargetForPawn(board, file+1, rank+nextRank)) {
			String move = EngineUtils.toSimpleAlgebraic(file, rank, file+1, rank + nextRank);
			addMove(move, board, rv, alreadyInCheck);
			if(oneOnly && rv.size() > 0) {
				return rv;
			}
		}
		
		return rv;
	}
	
	private void addMove(String move, Board board, Map<String, Board> rv, boolean alreadyInCheck) {
		Board nextBoard = board.clone();
		if(move.charAt(3) == '1' || move.charAt(3) == '8') {
			nextBoard.applyMove(move + "=Q");
		} else {
			nextBoard.applyMove(move);
		}
		
		if(CheckDetector.inCheck(nextBoard, !alreadyInCheck)) {
			return;
		}
		
		if(move.charAt(3) == '1' || move.charAt(3) == '8') {
			rv.put(move + "=N", board.clone().applyMove(move + "=N"));
			rv.put(move + "=B", board.clone().applyMove(move + "=B"));
			rv.put(move + "=R", board.clone().applyMove(move + "=R"));
			rv.put(move + "=Q", board.clone().applyMove(move + "=Q"));
		} else {
			rv.put(move, nextBoard);
		}
	}

	@Override
	public Map<String, Board> generateMoves(Board board) {
		Map<String, Board> rv = new HashMap<String, Board>();
		
		BitBoard bitBoard = board.getBitBoard();
		long pieces = bitBoard.getBitmapColor(board.getPlayer()) & bitBoard.getBitmapPawns();
		while(pieces != 0) {
			long nextPiece = Long.highestOneBit(pieces);
			pieces ^= nextPiece;
			int[] coords = BitBoard.toCoords(nextPiece);
			rv.putAll(this.generateMoves(board, coords[0], coords[1]));
		}
		
		return rv;
	}
}
